package com.sky.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.entity.Dish;
import com.sky.entity.DishFlavor;
import com.sky.entity.Setmeal;
import com.sky.json.JacksonObjectMapper;
import com.sky.mapper.DishMapper;
import com.sky.mapper.DishFlavorMapper;
import com.sky.mapper.DishSetmealMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.result.PageResult;
import com.sky.result.Result;
import com.sky.service.DishService;
import com.sky.vo.DishVO;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.bridge.Message;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Service
@Slf4j
public class DishServiceImpl implements DishService {
    @Autowired
    private DishMapper dishMapper;
    @Autowired
    private DishFlavorMapper dishflavorMapper;
    @Autowired
    private DishSetmealMapper dishSetmealMapper;
    @Autowired
    private SetmealMapper setmealMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result insertDishWithFlavor(DishDTO dishDTO) {
        //向菜品表中插入数据
        Dish dish = Dish.builder()
                .name(dishDTO.getName())
                .price(dishDTO.getPrice())
                .categoryId(dishDTO.getCategoryId())
                .image(dishDTO.getImage())
                .status(dishDTO.getStatus())
                .description(dishDTO.getDescription())
                .build();
        int InsertResult=dishMapper.insert(dish);
        if(InsertResult>0){
            log.info("菜品添加成功");
            Long dishId=dishMapper.getDishId(dishDTO.getName());
            //向口味表中添加n条数据
            List<DishFlavor> dishFlavorsList=dishDTO.getFlavors();
            for (DishFlavor dishFlavor : dishFlavorsList) {
                dishFlavor.setDishId(dishId);
                dishflavorMapper.insertDishFlavor(dishFlavor);
            }
            //清除指定分类的redis缓存
            redisTemplate.delete("dish_"+dishDTO.getCategoryId().toString());
            return Result.success();
        }else{
            return Result.error("菜品添加失败");
        }
    }

    @Override
    public Result<PageResult> dishPageQuery(DishPageQueryDTO dishPageQueryDTO) {
        int page = dishPageQueryDTO.getPage();
        int pageSize = dishPageQueryDTO.getPageSize();
        //开始分页
        PageHelper.startPage(page, pageSize);
        Dish dish= Dish.builder()
                .name(dishPageQueryDTO.getName())
                .status(dishPageQueryDTO.getStatus())
                .categoryId(dishPageQueryDTO.getCategoryId())
                .build();
        Page<DishVO> dishPage=dishMapper.dishPageQuery(dish);
        PageResult pageResult=new PageResult();
        pageResult.setTotal(dishPage.getTotal());
        pageResult.setRecords(dishPage.getResult());
        return Result.success(pageResult);
    }

    @Override
    @Transactional
    public Result deleteDish(String ids) {
        String[] idList = ids.split(",");
        for (String id : idList) {
            Long dishId = Long.parseLong(id);
            //调用mapper查询套餐中是否有该菜品
            int result = dishSetmealMapper.getDishUnionSetmeal(dishId);
            //判断该菜品是否包含在套餐中
            if(result>0){
                return Result.error(MessageConstant.DISH_BE_RELATED_BY_SETMEAL);
            }
            //判断该菜品是否起售
            Dish dish = dishMapper.getDish(dishId);
            if(dish.getStatus().equals(StatusConstant.ENABLE)){
                return Result.error(MessageConstant.DISH_ON_SALE);
            }
            //删除该菜品和该菜品信息对应的口味信息
            dishMapper.delete(dishId);
            dishflavorMapper.delete(dishId);
            log.info("菜品id为{}删除成功",dishId);
            //清除所有redis缓存
            Set keys = redisTemplate.keys("dish_*");
            redisTemplate.delete(keys);
        }
        return Result.success();
    }

    @Override
    public Result updateStatus(Integer status, Long id) {
        Dish dish= Dish.builder()
                .status(status)
                .id(id)
                .build();
        int result=dishMapper.update(dish);
        //如果菜品停售成功，则将菜品关联的套餐也停售
        if(result>0 && status.equals(StatusConstant.DISABLE)){
            //根据停售的菜品id获取套餐id
            List<Long> setmealIds=dishSetmealMapper.getSetmealId(id);
            //根据套餐id,将停售菜品的套餐状态设为停售
            for (Long setmealId : setmealIds) {
                Setmeal setmeal=Setmeal.builder().status(StatusConstant.DISABLE).id(setmealId).build();
                setmealMapper.update(setmeal);
            }
        }
        //清除所有redis缓存
        Set keys = redisTemplate.keys("dish_*");
        redisTemplate.delete(keys);
        return Result.success();
    }

    @Override
    public Result<DishVO> showDish(Long id) {
        //定义菜品响应数据
        DishVO dishVO=new DishVO();
        //调用mapper获取菜品信息
        Dish dish=dishMapper.getDish(id);
        //将除口味信息外所有信息封装到dishVO中
        BeanUtils.copyProperties(dish,dishVO);
        //获取菜品所有口味信息
        List<DishFlavor> dishFlavors=dishflavorMapper.getFlavor(id);
        //封装口味信息
        dishVO.setFlavors(dishFlavors);
        return Result.success(dishVO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result updateDish(DishDTO dishDTO) {
        //定义菜品对象
        Dish dish= new Dish();
        BeanUtils.copyProperties(dishDTO,dish);
        //更新菜品信息
        dishMapper.update(dish);
        //删除原菜品口味信息
        dishflavorMapper.delete(dishDTO.getId());
        //将新的菜品口味信息放入数据库
        for (DishFlavor flavor : dishDTO.getFlavors()) {
            flavor.setId(dishDTO.getId());
            dishflavorMapper.insertDishFlavor(flavor);
            log.info("id为{}的菜品添加口味信息成功",dishDTO.getId());
        }
        //清除所有redis缓存
        Set keys = redisTemplate.keys("dish_*");
        redisTemplate.delete(keys);
        return Result.success();
    }

    @Override
    public Result<List<Dish>> dishList(Long categoryId) {
        Dish dish=new Dish();
        dish.setCategoryId(categoryId);
        dish.setStatus(StatusConstant.ENABLE);
        //调用mapper根据分类Id获取菜品信息
        List<Dish> dishData=dishMapper.getDishList(dish);
        return Result.success(dishData);
    }

    /**
     * 缓存菜品功能
     * @param categoryId
     * @return
     */
    @Override
    public Result<List<DishVO>> list(Long categoryId) {
        List<DishVO> dishVOList=new ArrayList<>();
        //查询redis中是否有该分类数据
        ValueOperations StringOperation = redisTemplate.opsForValue();
        List<DishVO> dishData = (List<DishVO>) StringOperation.get("dish_" + categoryId.toString());
        if(dishData==null){
            //redis中没有该分类数据，从数据库中查找并放入redis中
            Dish dish=Dish.builder().status(StatusConstant.ENABLE).categoryId(categoryId).build();
            List<Dish> dishList = dishMapper.getDishList(dish);
            for (Dish d : dishList) {
                DishVO dishVO=new DishVO();
                BeanUtils.copyProperties(d,dishVO);
                //根据菜品id查询对应的口味
                List<DishFlavor> flavor = dishflavorMapper.getFlavor(d.getId());
                dishVO.setFlavors(flavor);
                dishVOList.add(dishVO);
            }
            //将菜品数据按分类放入redis
            StringOperation.set("dish_" + categoryId.toString(),dishVOList);
            return Result.success(dishVOList);
        }else{
            return Result.success(dishData);
        }
    }



}
